home *** CD-ROM | disk | FTP | other *** search
Lisp/Scheme | 1994-05-28 | 4.7 KB | 201 lines | [TEXT/xlsp] |
- #-:classes (load "classes")
-
- ; On an IBM PC, ANSI escape sequences probably won't work unless you use
- ; NNANSI.SYS because the buffered output used bypasses the BIOS.
-
- ; This is a sample XLISP program
- ; It implements a simple form of programmable turtle for VT100 compatible
- ; terminals.
-
- ; To run it:
-
- ; A>xlisp turtles
-
- ; This should cause the screen to be cleared and two turtles to appear.
- ; They should each execute their simple programs and then the prompt
- ; should return. Look at the code to see how all of this works.
-
- ; Get some more memory
- (expand 1)
-
- ; delay a while
- #+:times (defun pause (time)
- (let ((fintime (+ (* time internal-time-units-per-second)
- (get-internal-run-time))))
- (loop (when (> (get-internal-run-time) fintime)
- (return-from pause)))))
- #-:times (defun pause () (dotimes (x (* time 1000))))
-
- (defmacro delay () (pause 0.5))
-
-
- ; Clear the screen
- (defun clear ()
- (princ "\033[H\033[2J"))
-
- ; Move the cursor
- (defun setpos (x y)
- (princ "\033[") (princ y) (princ ";") (princ x) (princ "H"))
-
- ; Kill the remainder of the line
- (defun kill ()
- (princ "\033[K"))
-
- ; Move the cursor to the currently set bottom position and clear the line
- ; under it
- (defun bottom ()
- (setpos *bx* (+ *by* 1))
- (kill)
- (setpos *bx* *by*)
- (kill))
-
- ; Clear the screen and go to the bottom
- (defun cb ()
- (clear)
- (bottom))
-
-
- ; ::::::::::::
- ; :: Turtle ::
- ; ::::::::::::
-
- ; Define "Turtle" class
- (defclass Turtle ((xpos (setq *newx* (+ *newx* 1))) (ypos 12) (char "*")))
-
- ; Message ":display" prints its char at its current position
- (defmethod Turtle :display ()
- (setpos xpos ypos)
- (princ char)
- (bottom)
- self)
-
- ; When the character is set, we want to redisplay
- (defmethod Turtle :set-char (c)
- (setq char c)
- (send self :display))
-
- ; Message ":char" sets char to its arg and displays it
- (defmethod Turtle :set-char (c)
- (setq char c)
- (send self :display))
-
- ; Message ":goto" goes to a new place after clearing old one
- (defmethod Turtle :goto (x y)
- (setpos xpos ypos) (princ " ")
- (setq xpos x)
- (setq ypos y)
- (send self :display))
-
- ; Message ":up" moves up if not at top
- (defmethod Turtle :up ()
- (if (> ypos 0)
- (send self :goto xpos (- ypos 1))
- (bottom)))
-
- ; Message ":down" moves down if not at bottom
- (defmethod Turtle :down ()
- (if (< ypos *by*)
- (send self :goto xpos (+ ypos 1))
- (bottom)))
-
- ; Message ":right" moves right if not at right
- (defmethod Turtle :right ()
- (if (< xpos 80)
- (send self :goto (+ xpos 1) ypos)
- (bottom)))
-
- ; Message ":left" moves left if not at left
- (defmethod Turtle :left ()
- (if (> xpos 0)
- (send self :goto (- xpos 1) ypos)
- (bottom)))
-
- ; :::::::::::::::::::
- ; :: Circular-List ::
- ; :::::::::::::::::::
-
-
- ; Define a class to represent a circular list
- (defclass Circular-List (prog pc))
-
- ; Replace :isnew with something more appropriate
- (defmethod Circular-List :isnew (&optional list)
- (setf prog list pc list)
- self) ; return self
-
- ; Method to get next item in list
- (defmethod Circular-List :next ()
- (when (null pc) (setq pc prog))
- (prog1 (car pc) (setq pc (cdr pc))))
-
-
- ; :::::::::::::
- ; :: PTurtle ::
- ; :::::::::::::
-
- ; Define "PTurtle" programable turtle class
- (defclass PTurtle (prog) () Turtle)
-
- ; Message ":program" stores a program
- (defmethod PTurtle :program (p)
- (setf prog (send Circular-List :new p))
- self)
-
- ; Message ":step" executes a single program step
- (defmethod PTurtle :step ()
- (when prog (send self (send prog :next)))
- (delay)
- self)
-
- ; Message ":step#" steps each turtle program n times
- (defmethod PTurtle :step# (n)
- (dotimes (x n) (send self :step))
- self)
-
-
- ; ::::::::::::::
- ; :: PTurtles ::
- ; ::::::::::::::
-
- ; Define "PTurtles" class
- (defclass PTurtles (Turtles))
-
- ; Message ":make" makes a programable turtle and adds it to the collection
- (defmethod PTurtles :make (x y &aux newturtle)
- (setq newturtle (send PTurtle :new :xpos x :ypos y))
- (setq Turtles (cons newturtle Turtles))
- newturtle)
-
- ; Message ":step" steps each turtle program once
- (defmethod PTurtles :step ()
- (mapcar #'(lambda (Turtle) (send Turtle :step)) Turtles)
- self)
-
- ; Message ":step#" steps each turtle program n times
- (defmethod PTurtles :step# (n)
- (dotimes (x n) (send self :step))
- self)
-
-
- ; Initialize things and start up
- (defvar *bx* 0)
- (defvar *by* 20)
- (defvar *newx* 0)
-
- ; Create some programmable turtles
- (cb)
- (definst PTurtles Turtles)
- (setq t1 (send Turtles :make 40 10))
- (setq t2 (send Turtles :make 41 10))
- (send t1 :program '(:left :left :right :right :up :up :down :down))
- (send t2 :program '(:right :right :down :down :left :left :up :up))
- (send t1 :set-char "+")
- (defun doit ()
- (progn
- (cb)
- (send t1 :step# 8)
- (send t2 :step# 8)
- (send Turtles :step# 8)))
- (doit)
-
-